Repository navigation
Conversation
按明确要求:段位認定结算页不再用 CSS 重画,直接把原作画面素材搬上屏。
## 素材
`public/assets/maimai/` 下 7 张 PNG,从 maimai DX 客户端 `resources.assets` 里
用 UnityPy 提取(那一个文件 5916 张 Texture2D,`UI_DNM_*` 家族 159 张):
仓库文件 客户端贴图 用途
result-dani.png UI_DNM_Result_Base_01 「段位認定」整屏底图 980×928
result-random.png UI_DNM_Result_Base_03 「ランダム段位認定」整屏底图
track-plate.png UI_DNM_Result_musicBase_01 逐题行底板 576×124
stamp-clear.png / stamp-fail UI_DNM_Icon_Result_01 / _02 逐题「可」/「不可」印
verdict-clear.png / -fail UI_DNM_Icon_Clear / NoClear 「合格」/「不合格…」印
提取脚本留在 scripts/extract-maimai-assets.py(开发工具,不是应用依赖),
照它就能从任意一份客户端里重新提一遍。
## 页面
整屏底图就是那张成品图 —— 页头文字、格纹页眉、两侧水引(蝴蝶结 + 竖绳 + 流苏)、
下半部色带与左下角那格白框**全都烘焙在底图里**。所以:
- 档位挑战用 `_01`(「段位認定」),小/大随机段位用 `_03`(「ランダム段位認定」)——
原作本来就把这两件事分成两块屏,我们照它的分法;
- 标题 h2 只留给读屏(页头已经有了),`aria-labelledby` 不变;
- 删掉 CSS 画的 `.dan-cord` 水引与 `.dan-result-rankbox` 判定框、CSS 画的「可」印;
- 逐题卡改用原作底板撑起来,判定印是原作贴图;合格印盖在左下那格白框里(原作那一格
放的就是段位名/合格印,我们不发段位名,改盖判定印)。
分区数字是拿 Pillow 逐行逐列分类量出来的,不是估的:
页头带 0–15.1% · 奶油纸区 15.1–71.6% · 底部色带 71.6–100% ·
纸区可写横向 26–88%(左边 24.8% 以右是菱形装饰,88.9% 以左是水引)·
左下白框 x 8.7–31.6% / y 73.3–94.8%。
盘面比例锁死 `aspect-ratio: 980/928`,窄屏横向滚动而不是压扁底图。
顺带修一处真 bug:没有成绩时「达成率」/「总达成率」的那一个「—」被套上了金色描边
数字(6px 描边 + 两层伪元素),在屏幕上被画成一根小横杠。现在只有真有数字时才上金色。
## 版权
这些美术素材有版权,不属于本仓库 MIT 许可范围,也不随上游项目走 —— docs/dan.md
里写清了来源、映射表与「要不要留在分支上由部署的人自己判断」。
这一条替换了早先「用 CSS 重画、不搬游戏美术」的做法(那是为了避免把游戏美术带进
MIT 仓库),按 2026-10-09 的要求改为直接上素材。
## 验收
- 单测 **309/309** 不变(这轮只动 public/ 前端与文档,没碰服务端逻辑)。
- 整轮结算 E2E 全绿:底图断言现在验的是 `result-dani.png` 与 `980 / 928` 比例,
判定印验 `alt`/`src`(合格 / verdict-clear.png)与逐题印(通过 / stamp-clear.png)。
- 随机段位 E2E 新增一条:底图必须是 `result-random.png`(不能借档位挑战那版)。
- 像素探针重标后全绿:「可」印现在是红花 + 红字,不再是奶油底方印,
所以白像素配额从 1000 降到 400,并加了一条「红占比 < 70%」——要防的仍然是
「糊成一整块红、里面的字读不出来」。
- docs/dan.md 补了截图(docs/images/dan-settlement.jpg)与素材来源一节。
按明确要求:原作画面要叠在底下、组件要按官方位置拼起来,尤其是**结算分数**
要换成官方素材 —— 上一版只是把底图铺上、内容按底图分区粗摆(位置差几十像素),
数字还是 CSS 画的字体。这一版两件事都换成官方素材。
## 版式:从预制体里读坐标,不再按分区估
用 UnityPy 读 `CourseResultProcess` 与逐题行 `UI_CMN_KOP_TrackData` 里每个
RectTransform 的 anchors / anchoredPosition / pivot / sizeDelta,按
「美术坐标 = 屏幕中心 + 局部位置」换算到 980×928 底图上:
逐题行 x 267–843(576 宽 = 官方 640 × 0.9)、高 124
第 1 行 y 152,行距 122,共四行(152 / 274 / 396 / 518)
行首的印 108×108(官方原始尺寸,上一版缩成了 50)
达成率数字 字高 46(招牌位 368 宽正好放下 9 个字符)
底部白框 x 85–310 / y 680–880(原作放段位名牌那一格)
心 100×100,圆心 (434, 790)(原作剩余生命那一格)
总达成率 x ~470–965 / y ~620–845(官方 Text_01 / Num_DXScore 那一区)
盘面改成固定 980×928 的绝对像素舞台(不再 `aspect-ratio` 等比缩放),窄屏让盘面
横向滚动 —— 这样「一个数字多宽」这类关系到还原度的结论可以直接抄官方数字。
## 分数:官方数字图集逐格切
- `UI_CMN_Num_26p / 70p / 90p`(136×160 / 300×348 / 356×420,规整 4×4 网格,
每格由同名 Sprite `_0 … _14` 定 rect)。逐题达成率用 70p、总达成率用 90p、
LV 用小号 26p。
- 图集是**纯白剪影**(游戏运行时才染色),所以描边不是 CSS 画的:每格拆成
「官方 `_Outline` 剪影当遮罩上深色 + 官方填充图集」两层真元素。试过两个
background 层的写法,不行 —— background 层没法单独染色,伪元素又只能画在宿主
背景之上(描边会盖住填充)。
- 对照表是一张张看出来的:数字族 `[0-9]` `[10]'+'` `[11]'-'` `[12]','`
`[13]'·'`(居中的圆点,这套字体的小数点就画在字高中线上)`[14]'%'`;
金色分数族 `[10]'+'` `[11]'/'` `[12]'%'` `[13]'.'`。放大 6 倍 + 量墨迹包围盒确认。
- DX 分数用官方金色 `UI_NUM_Score_0001111_Gold`(带小数点 [13]),评级用
`UI_CMN_TabTitle_Rank_*`,心用 `UI_DNM_Base_Life_01`(绿)/ `_03`(红),
DX 标签用 `UI_RSL_DXScore_Base`。
## 顺手修的
- `.dan-total-num` / `.dan-track-dxnum` 是 `<span>`,`justify-content` 静默无效 ——
数字没有右对齐到官方格子,总达成率与它的「%」之间空出 ~90px。改成 flex 容器。
- 这一轮的范围说明(档位区间/题数/限时/抽题方式/标签)从成品屏里挪到屏幕下方:
原作那张纸没有放这行字的位置,硬塞只能压住页头或第一行。
- 删掉未使用的 life-heart.png(底盘本身自带心形)。
## 验收
- 单测 **309/309**(这轮只动 public/ 前端、提取脚本与文档)。
- 结算 E2E:新增一条**坐标断言** —— 「行内组件互不重叠、也不伸出底板」(逐块量
boundingRect),以及「盘面 980×928」「第 1 行 y=152、行距 122、行宽 576」
「印 108×108」「达成率是 70p 填充 + _Outline 描边、字高 46」「DX 分数是金色分数
图集」;「按难度上色」那条改成不变式(同难度必然同色)—— 同一轮四道都抽到
1700 时它本来就该是同色,旧写法会假失败。
- 随机段位 E2E:新增「每张卡也有官方数字达成率与评级徽章」。
- 像素探针重写:数字的着色(白填充 + 深色描边有多少像素)只能数像素验,
DOM 层面查不出「遮罩没生效、数字变全白」这种事。全部 PASS。
- docs/dan.md 补了坐标来源、字符对照表、素材表(26 → 25 张)并换了新截图。
达成率才是那一行最该上分色的数字:换成官方分数图集
UI_NUM_Score_0001111_{Blue,Gold,Red} + 官方彩色「%」字形(UI_RSL_Score_Per_*),
按达成率三档换色(≥100% 金 / ≥97% 蓝 / 更低红)。官方那张
UI_NUM_Score_0001111_Base 是一张空图集(16 格一个字形都没有),照它渲染就是
一片看不见的灰影,所以不搬、也别用 —— 官方那套本来就是三色。
DX 分数那一格显示的是单题 rating、不是 DX 分数比率,三色专门留给达成率,
它改用白字族剪影染深蓝(numText 新增 color 参数:用图集当遮罩 + 纯色背景,
也就是游戏里给白字族上色的做法)。
逐题行的乐曲边框上一版直接没了(只留了 musicBase 底板)。官方那五张
UI_CMN_RSL_KopMBase_{BSC,ADV,EXP,MST,MST_Re} 把难度色与难度名烘死在图里,
套不上我们自己的 CF 分档,所以照它逐像素量出来的版式用 CSS 画一层:
外圈浅色环 + 主色场 + 底部浅色带 + 左侧白曲绘槽 + 深蓝标题条(带官方那圈白边)
+ 白色达成率框 + 行首小牌(压在曲绘槽左上角,就是官方 JaketTrack 的位置)
+ 右侧评级/LV/限时/DX 分数牌。颜色由 cfRatingColor(...).tone → TRACK_TONE
经 --tc1/--tc2 给,所以任何档位色都能上;难度名牌写我们自己的档位区间
(例如 1600–1899)而不是官方的 MASTER。
顺带:删掉没人用的 num-70p 图集;把边框、达成率配色、DX 分数染色的断言
加进 dan-settlement-check,像素探针加抠一份总 DX 分数(这一格曾经静默渲染成
灰影,DOM 层面查不出来);dan-custom-check / dan-random-check / 309 个单测全绿。
上一版满屏字墙:右边一列挤了评级 / 难度分 / 限时 / DX分数 四件,左边曲绘槽是 一块纯白(在深色里就是块洞),底部白框外的印比框还大、右边两个数字各飘各的。 这一版按「哪块信息跟谁走」重排: - 逐题行:单题 rating 的「DX分数」白牌挪到左边、挂在题号牌下面;CF 难度分并进 难度名牌(大字档位 rating + 小字 CF 区间);右边只留评级徽章与限时白牌, 两件都按官方 UI_GameType / DerakkuScore_NUM 那两格摆。 - 曲绘槽换成按档位色上色的题号牌(斜纹 + --tc1/--tc2 渐变),左上角跟着边框圆角, 不再是一块纯白。 - 评级徽章放大到 106×51(官方 UI_Difficulty 那一格的大小),限时牌文字居中。 - 底部:合格印缩进底图那个白框里(白框实测 (74,672) 240×230),印下面写通关题数; 右侧两行右对齐到同一条边(总达成率 / でらっくスコア),DX 那一行挪到底图那条 白缎带上(实测 y 812–852 / x 609–968)—— 官方本来就拿缎带当分数面板, 浮在旁边会剩一块看着像空框的白。 - 超时/失败那一屏:达成率与总达成率的占位「—」改成白字族剪影染深蓝, 之前是纯白剪影铺在白框上,等于看不见。 E2E 也跟着改:布局断言换成新坐标(含「右边一列只留两件」与「印不许糊出白框」), 并修正「超时那一轮」——上游合并后服务端不再用本地轮询判超时(要先成功同步一次 该账号的提交),改成走同一条判定链里不需要同步的那一支(计时器 completed 且 结束时间晚于限时),仍然是服务端判出来的失败轮次。314 个单测 / 三个 E2E / 像素探针全绿。
- 「でらっくスコア」那张官方标签(UI_RSL_DXScore_Base,226×54)本身是个**框**: y 0–25 是蓝底白字,y 26–50 留了一块 218×25 的白 —— 那块白就是给分数用的。 上一版把数字排在框右边,这一版按原尺寸放整张框、数字写进框里那块白 (padding-right 8px 右对齐),整张框落在底图那条白缎带上。 - 总达成率那一行整体往下挪 22px(top 664 → 686),标签从 .74rem 放大到 .92rem/800, 跟下面那块框错开、也不再像贴在色带上沿。 E2E 换成量新关系:右下两块右对齐到同一条边(x 945)、DX 数字必须**落在标签框 的框内**、总达成率那行位置与标签高度。单测 314、三个 E2E、像素探针全绿。
底图下半部那条色带里有三块**挖白的空面板**((503,663) 213×52、(753,677) 104×38、 (608,810) 360×80)—— 那是原作留给运行时贴图的位置,运行时被盖住,所以底图上留白。 我们不需要显示那么多信息,白块露出来只会看着像「空框」,上一版还被迫把 でらっくスコア 那张标签往白块的形状里塞。 新增 scripts/patch-maimai-result-band.py,按底图自己的花纹把这三块续画填掉: - 色带是平涂竖向色块 + 斜向橙色折线,水平方向**严格周期**:干净区自比,p=115 时 平均差只有 2.8(再往上都是倍频),所以整块矩形都能从 x±k·115 的同相位列搬过来, 折线与色块接缝都对得上; - 不按阈值抠白像素:挖白边缘有一圈跟底色混出来的半透明浅灰,抠出来总会漏一圈 光晕;按连通域量出矩形(外扩 3px)整块替换更干净; - 取色列避开画布左右边框(深红)与左下角那块段位名牌 —— 那一格留着盖合格印; - 已补过的图认得出(矩形里没有近白像素就跳过),所以重复跑不会沿着折线累积漂移。 底图两个变体(result-dani / result-random)都补了,页面版式不用再迁就白块。 314 个单测 / 三个 E2E / 像素探针全绿。
第 13 轮反馈。上一版把底图那三块挖白的槽位填掉了 —— 那是错的:那三块白正是官方写 运行时文字的位置,填掉等于自己把位置抹了。所以这一轮先把补丁撤销:删掉 scripts/patch-maimai-result-band.py,result-dani.png / result-random.png 回到原始素材 (`git checkout 9977c4b^`),内容照底图预留的白格摆。 - 左下白框改回**档位名**(原版那一格就是段位名牌):深棕重字 + 米白描边 + 一点投影, 名字下面一行小字写「合格 · 4 / 4 道通关」;不再盖合格印(verdict-clear/fail.png 已删)。 - 底部照底图预留的白格摆:`总达成率` 写进 (503,663) 354×52 那格白(居中),大数字落 在下面的色带上、右端对齐 x 945;`DX分数` 与数字写进 (608,810) 360×80 那条白牌, 标签在左、数字在右,两处都是深蓝 #16306b。上一版自造的「DX分数合计」标签删掉 (dxscore-label.png 也随之不用了)。 - **数字改密排**:数字图集每格留白很多(90p 格宽 89、字形只有 63),照格宽排会读成 「一个字一个字分开」。numText 现在按每族的 advance 把每格右边收回一点 (n90 67/105、n26 24/40、分数族 67/98),最后一格不收回,免得尾巴多一段空白。 - **评级徽章换成 `UI_GAM_Rank_*`**(游戏内那套单级全套 14 张)。之前用的 `UI_CMN_TabTitle_Rank_*` 是**页签标题**上的区间图:AAA 那张画的是「A~AAA」、 BBB 是「~BBB」,摆在逐题卡片上根本不是那一级的评级,而且它没有 D/C/B/BB/A/AA, 低分全挤在同一张牌上。徽章框顺带放到 132×52。 - 逐题卡:难度名牌只留档位名一行(同一张卡上达成率与单题分已经给了具体分数,再摆 CF 分与分数分组只是重复);单题 DX 分数不再叠描边层(小字叠描边就糊成一团); 达成率那行小字改成官方那三个字「達成率」,数字贴白框左边排、字高 41→44。 - 心照官方放大到 200×200,里面写「四道里过了几道」(数字图集里没有「/」,退回普通 文字会被两边数字的描边吃掉,所以不写 4/4)。 scripts/dan-settlement-e2e.mjs 重写:三个场景(四道满分成 / 达成率 100.8·98.5·96·92 四道分色 / 一道超时不合格),逐条断言卡片坐标、白格落位、徽章素材、三档颜色,以及 「数字密排」的每字步进;顺手出文档插图(含分色那张)。题目名不再伪造 —— 上一版探针 自己写了「段位認定第 N 道」,用户看到的正是这个假名。314 个单测 / E2E / 像素探针全绿。
第 13 轮的第二次返工(对着渲染图逐条改): - **字距**:分数族的「.」那一格墨迹只有 33px 宽、格子却有 74,左右各留 20px 空白 —— 照格宽排出来就是「403 ・ 1998」中间断一截;末尾那个「%」是 80×80 的方图,四周同样 留白,直排又多一截。现在 numText 对窄字形按**墨迹裁格**(格宽取墨宽、背景左移掉左空、 步进另给 36),「%」放大到 1.1 倍字高再用负边距抵掉左边留白。数字本身仍是等宽步进 (和官方一致),只是不再被格子留白撑开。 - **小数点**:白字族图集里的小数点是个**居中方块**(26p 那张只有 8×8、y 18..25), 小字号下读起来像断字符 —— DX 分数(单题 rating / DX 总分)改成**自画的贴底方块** (边长 0.19 字高,底边压在数字基线上)。达成率那串仍用图集自带的方形小数点(官方那张 就是居中的方块)。 - **卡片分数格**:白框 328 → 300 宽。原来框尾 439、徽章从 436 起,徽章压着框的一角, 看着像徽章占了分数格;现在框尾 411、徽章左 436,中间留 25px。E2E 新增一条断言: 数字不许溢出白框、白框与徽章至少留 10px(数字宽度取里面那串 .dan-num 的实际宽度)。 - **底带**:`总达成率` 字号 30 → 26,按实测白区 `x 503..708` 居中(原来排在 583..690, 偏右);大数字下移 8px、字高 60 → 66、右端 945 → 950;`DX分数` 那一行原来跟着 360×80 的白牌垂直居中,可白牌下半截被折页斜切掉一块,文字一半落在折线上,现在靠上排 (y 816 起)。 顺带修掉 E2E 里两处坐标系混用:行内格子是行坐标、印与徽章是底图坐标,`inRow()` 之前 给徽章又加了一次行原点,导致扣图与断言都在错的偏移上(像素探针里「可」印的红像素因此 从 2820 掉到 999)。 314 个单测 / 三个场景的 E2E / 像素探针全绿。
…tal label - **小数点不再起飞**:自画的小数点方块用了 `<b>`,而 `.dan-num-char > b` 那条规则是 `position: absolute; inset: 0`(给填充/描边层用的),方块被顶到格子上边 —— 看起来 就是「小数点变成单引号」。改成 `<span>`,方块回到基线上(实测数字墨迹底 y 842)。 - **「DX分数」和分数对齐**:实测标签的 CJK 基线比数字墨迹底低 11px,给标签 `margin-top:-11px`, 现在两边底线都落在 y 842(逐像素复量确认差 0px)。 - **`总达成率` 往上移 6px**:容器不动(白格坐标要留着),用 `padding-bottom: 12px` 把居中 的文字顶上去。 E2E / 像素探针 / 314 个单测全绿。
上一版为了「小数点别像断字符」,在 `numText()` 里塞了三样特例:逐字墨迹裁格、自画
贴底方块、每字不同的步进。那是把一条文本拆成手工排版 —— 不但没必要,还把小数点挤到
数字上(`ink` 裁掉左空之后它紧贴着前一个字)。
这一版全删掉,回到图集自己的排法:
- **一个字形一格、格子之间按 `advance` 等距**(分数族 74→67、90p 89→67、26p 34→24),
小数点、逗号、加号都走同一条路;`NUM_FONTS` 里的 `ink` / `baseline` / `dot` 三个字段
与 CSS 的 `.dan-num-dot{,ink}` 一起删了,`numText()` 回到「裁格 → 收边距」两步。
- DX 分数的小数点直接用图集 `[13]` 那一格:这套字形的小数点本来就画在字高中线上
(26p 那张 8×8、y 18..25),官方「101.0000%」用的也是同一个居中方块。居中排之后
两侧各留半格,不再和数字糊在一起。
- 「%」那一处保留一条负边距:它是 80×80 的独立图片、左边自带 8px 留白,不加的话
数字和 % 之间会空出一截(官方那里几乎贴着)。
E2E / 像素探针 / 314 个单测全绿。
对着官方那张结算图把逐题卡重排了一遍: - **删掉档位名牌**(原来写「上级」「初级」那一格)。官方那格烘的是难度名(`MASTER 大師`), 我们这边对应的档位名在同一张卡上跟题号、达成率、单题 rating 重复,而且占掉半个标题条。 标题条因此从 `x 220` 左移到 `x 122`、宽度 334→432,一路铺到边框右端(122+432=554)。 - **曲绘槽换成题号牌**:上行写完整题号(`1554C` = 场次 + 小问,原来只写一个小问字母, 一屏四张卡看不出是哪道题),下行写这题在 CF 上的 rating(`dan_stages.difficulty`)。 原来槽里是档位色渐变 + 斜条纹,一屏四张就是四块看不懂的色块 —— 现在就是一块白牌。 - **小数点**:白字族里根本没有句点这一格(`[13]` 是中黑点、`[12]` 是逗号),照它排出来就是 「断字符」。改成**借分数族 `[13]`** —— 那才是这套数字里真正的句点,官方「101.0000%」用的 就是它。借字形按自己的格子高定比例、在本族格子里横向居中,一条公式,没有逐字表。 - **标签与数字的水平对齐**:两处 `DX分数` 都改成 `align-items: baseline`,数字那一侧由 `numText` 的 `baseline` 选项补 `(1 − baseline) × 字高`(flex 认的基线是格子底边,而图集里 数字的墨迹底线在格高的 `baseline` 处)。实测两边基线都落在同一条 y 上,不再靠手调的 -11px。 - `总达成率` 字号 26 → 23。 E2E 里那条「难度名牌只写名字一行」换成「档位名牌已删掉、标题条左移顶上去」与 「曲绘槽里写完整题号 + CF rating」两条断言。E2E / 像素探针 / 314 个单测全绿。
对着原版逐像素量了一遍(`official-dani.png` 里「101.0000%」那只方块): - **小数点根本没走上「借用」那条路**。白字族的索引表里也定义了 `.`(映射到 `[13]`), 所以我上一版写的 `font.chars[ch] === undefined && ch === '.'` 永远不成立 —— 渲染出来的 还是白字族那一格:26p 只有 8×8、90p 24×24,小字号下量下来只有 **6×6**、还浮在字高中间 (实测它底边比数字基线高 8px)。现在改成「本族这一格画得不对,一律借分数族的句点」, 直接覆盖映射。 - **借来的句点按基线摆**:官方那只方块的底边压在数字基线上(量下来差 0px)。所以借来的 字形按自己的格子高定比例、横向居中,纵向把墨迹底线压到本族基线上(`baseline` 0.827 对 90p 的 0.886)。复量:句点 10×12px、底边 y 843,数字基线 y 842 —— 差 0/1px。 - **卡片改平色**:主色场原来是 `--tc1 → --tc2` 的上下渐变,一屏四张卡就是四块深浅不一的 色块;现在 `background: var(--tc1)`,只有底部那条浅色带(原版就有)。 - **曲绘槽底色**取卡片主色的浅色版本(`color-mix(... 42%, #fff)`),不再是纯白;槽里题号 1rem → **1.3rem**、rating .68 → **.85rem**。 - 底带 `DX分数` 那一行上移 6px(白牌内边距 6 → 0)。 E2E / 像素探针 / 314 个单测全绿。
…e STAGE chip 对着官方图(`official-dani.png`)逐像素量了两处,然后按量到的结果改: - **小数点为什么这么粗**:之前用的是**分数族**那一格(33×41 / 74×98),它比数字本身粗一圈, 一个族的字形混到另一个族里,粗细对不上。现在改回**本族 `[13]`**(26p 8×8、90p 24×24), 只按 `dotBaseline`(该格墨迹底线在格高里的比例:26p 0.775 / 90p 0.6)把它从字高中线压到 **数字基线上** —— 官方那只方块的底边就是压在基线上的。复量:句点 6×7px、底边 y 842, 数字基线 y 843。同一个族 = 同一个粗细,也不再借用别的族。 - **行首「STAGE 01」小牌删掉**:官方那张牌压在曲绘上,我们没有曲绘,它就只是在左上角多挂 一块深蓝方块。节点不再渲染,CSS 留 `display:none` 兜底。 - **达成率数字改右对齐**:满 100 的那串(`100.8000%`)右端固定在同一个位置,不到 100 的 少一位数就少在左边(`96.0000%` 右端仍与 100 的齐平);左对齐时短的那串右端会缩回来一截。 E2E / 像素探针 / 314 个单测全绿。 关于**分数换色的档位**:查了官方评级表(萌娘百科 maimai 条目: [达成率与评级](https://moegirl.icu/zh-cn/Maimai%E7%B3%BB%E5%88%97),SSS+ 100.5000~101.0000、 SSS 100.0000~100.4999、SS+ 99.5000~99.9999、SS 99.0000~99.4999、S+ 98.0000~98.9999、 S 97.0000~97.9999、AAA 94.0000~96.9999 …),以及官方截图那张(四行都是 101.0000%,全是金)。 当前实现就是按这三组:≥100 金(SSS/SSS+)、≥97 蓝(S~SS+)、再低红。 如果这与你看到的原版不符,说一下具体是哪个分数段判错(例如 98.5 你看到的是红、100.0~100.4 看到的是蓝),我按你给的档位改。
…rs, export the original card art - **小数点下压后上面露出半个字**:背景图整块往下挪,把**上一格**的下半截带进了这一格。 只有被压过的那一格需要裁剪,所以给那一格单独加 `overflow: hidden`(其余格子不动, 免得把描边层裁掉)—— DX 数字本来就不带描边,安全。 - **达成率分色改成用户给的官方口径**:**≥97% 金、80~96.99% 红、<80% 蓝**(低分段是蓝, 不是红;原来按「高金/中蓝/低红」写的,红蓝对调了)。E2E 的期望值跟着改;那一轮的 合成用例只能落在金/红两档(评分曲线只在 ≥97% 段可逆,反推不出 <80% 的秒数)。 - **达成率数字右对齐**:满 100 的那串右端固定,不到 100 的少一位数就少在左边。 - 新增 `scripts/export-original-card.py`:把**原版**乐曲卡片素材原样导到 `docs/images/original-card/`(`UI_CMN_RSL_KopMBase_*` 五张难度边框 640×140、 `UI_DNM_Result_musicBase_01`、`UI_CMN_RSL_JaketTrack` / `JaketTrackNo_0` 等), 供逐像素对照。另存 `docs/images/dan-card.png`:当前渲染的第 1 张卡单独裁出来。 E2E / 像素探针 / 314 个单测全绿。
用户要求「照着原版素材画」,所以先量原版再重排,而不是继续手调。 量的是 `UI_CMN_RSL_KopMBase_MST`(官方常规结算页那圈行边框 640×140)。版式: 最外圈难度主色圆角框 → 左上难度名牌(**删掉**,我们的档位名已经写在整屏底图左下白框里) → 右上深蓝歌名条(删掉名牌后占满上面一整行)→ 左侧约 1/3 白色曲绘槽 → 歌名条下方一块 大白色达成率盒 → 盒下一条底带,底带**右端**是烘死「でらっくスコア」的白牌。 换算一条规则:`行内坐标 = (原版坐标 + 2) × 0.9`(原版 640×140 含外圈,我们的卡片内区 576×126)。 按用户口述的分配重排: - 顶部歌名条占满一整行(不再是一小段居中的条); - **DX 分数挪到卡片右下角**(原来在左下); - **限时写进下面那一条底带**的左侧(原来浮在右上角); - 难度名牌 / MASTER 不再出现; - 主色仍是单色平场(底部浅色带、曲绘槽取主色浅色版),去掉竖向渐变与白内环。 没碰:`scoreTone()`(≥97 金 / 80~96.99 红 / <80 蓝)、小数点借 `[13]` 与 `dotBaseline` 压基线、整屏底图那几块挖白面板、底部「DX分数 / 总达成率」条。 E2E 里那批逐题行坐标断言按新版式改写了语义(标题条整行、DX 在右下、限时在底带等), 顺手修掉页面侧模板字符串被注释里的反引号提前闭合导致的 `num is not defined`。 产物:`docs/images/dan-card.png`(我们的卡单独裁出,2×)、 `docs/images/dan-card-vs-original.png`(与原版并排)。 E2E / 像素探针 / 314 个单测全绿。
…ievement decimal on the baseline
Vendor the archived international stylesheet, M PLUS 1p webfonts and background artwork into public/vendor/maimai, and add theme.css plus theme.js on top of it. Also add a white-background logo variant: the original mark is baked into a dark PNG, the light one recolours the background to white and the white strokes to navy.
Link the fonts and theme layer, put the animated background in an iframe, add the mobile menu button and the back-to-top control, and move the hardcoded dark panels (analytics, heatmap, today, timer, circle sidebar, help sections) onto the light palette.
Same bg.html, day/night switched with ?night=1 or postMessage; assets/night holds recoloured copies of the official sky, clouds, aurora and rainbow.
theme-dark.css layers dark surfaces over the light skin, every rule scoped to [data-mm-theme=dark] so the light theme is untouched: header capsule, glass plates, official boxes, inputs, badges, notices, tables, dialogs and the page-specific components in theme.css section 17. The switch sits at the right end of the header bar, remembers the choice in localStorage and falls back to prefers-color-scheme. Each page resolves the theme in the head before first paint, and the background iframe is told day or night by postMessage, so switching never reloads it and the official entrance animation does not replay. The menu button was missing on circle, dx, stats and help; it is now on all six pages.
画布里的配色读不到 CSS 变量,改成脚本里两套调色板,换主题时由 stats-page.js 重画。
深色层的提示条与空热力格补上底色,窄屏筛选与状态标签交回响应式规则,换皮那一帧关掉过渡,编辑页与关注列表的窄屏排版一并收尾。
窄屏照搬官方 .common--box 的三档(3.75vw/2.727vw/30px 圆角与横条),硬阴影拆成偏移与颜色两段;直接落在背景花纹上的小字改成不透明底板,玻璃板提到 .88;统计页的 .analytics/.today-panel/热力图补上官方上下横条;菜单锁滚动移回媒体查询,标题与偏差清单里的数目对齐。
背景宿主页移出 vendor(那个目录只留原样素材),六个页面的 data-src 一并改到 /bg.html;品牌图标改成 CSS 背景,主题在 <html> 上,首帧就是对的,不再靠 JS 换 src;菜单展开后把窗口拉宽会自动收起,主题消息统一成 dark/light。
开发文档的 public/ 清单补上皮肤与深色相关文件;vendor 说明补上背景宿主页、字体符号家族与删掉的 wayback 注释;夜版贴图补一份 README 与 MD5 清单。
官方在 ≥769px 把闪点、曙光、彩虹和彩虹两端那片云都换成 PC 素材,夜版只挂了 SP 一份,宽屏就拿手机那张顶 PC 那格:彩虹两端那片云的 SP 版是被图片边界切平的窄裁版,铺进 PC 那格在画面中间露出两条平直切边。夜版素材补齐 SP / PC 两份并按同样的断点切换;彩虹两端那片云的 PC 底边、曙光两端(repeat-x 接缝)、彩虹后面那片云两端在夜里淡出。
Contributor
Author
|
按内容拆成两条:#3 是 dan 玩法与它的结算页,皮肤在 https://github.com/fbd777/Algorithm-DX/pull/4。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
这一套是什么
把整站前端换成 maimai 官方(国际服,PRiSM PLUS 时期)那套皮肤的复刻,并加上全站深色模式。样式来源是官网当时的
style.css与图片素材:参数、字体、断点都按官方照搬。主要变化
public/vendor/maimai/。style.css只改 URL(选择器与数值没动),img/**逐字节原样并附 MD5 清单;字体自托管 latin / latin-ext 子集,全站没有任何外链或 CDN。public/bg.html,用 iframe 铺在内容下面;结构、层级、尺寸、动画全部沿用官方style.css,官方那套全局选择器不会碰到本站布局。public/theme.css复刻官方.common--box的三档参数(3.75vw / 2.7273vw / 30px圆角、对应的硬阴影与横条),每块内容是「白底 + 上紫下粉横条 + 硬阴影」;直接落在背景花纹上的文字一律给不透明底板。<html data-mm-theme="light|dark">,顶栏开关负责记忆与跟随系统;public/theme-dark.css把卡片、表格、输入框、气泡、图表统一转深色;public/theme-night.css+public/assets/night/**是夜景背景贴图(按官方断点分 SP / PC 两份,跟官方一样切)。stat-charts.js里两套调色板,换主题时由mm-theme-change重画。与官方的偏差
有意偏差逐条写在
public/theme.css文件末尾(中文字形回退、版心宽度、记录列表密度、移动断点、图表、符号字体等,共八条);夜版素材的做法与淡边参数写在public/assets/night/README.md;vendor 目录只放原样素材,说明在它自己的 README 里。验证
node --test:314/314。vendor/maimai/img/MANIFEST.txt92/92 条字节数与 MD5 与官方归档一致。原有内容(dan 玩法部分,未改动)
做了什么
段位認定(dan)玩法 + 随机抽题 + 每日一题,以及把结算页按原作素材重做了一遍。前端改动为主。
玩法
docs/dan.md),仅用于展示,不是游戏里的 でらっくスコア,也不等于 B50 的增量。结算页(对着原作素材逐像素量出来的)
UI_DNM_Result_Base_01(随机段位用_03);底图上那几块挖白的空面板是原作留给运行时文字的位置,保持原样不重绘。UI_CMN_RSL_KopMBase_*量到的版式重画:外圈难度主色圆角 + 顶部歌名条占满一行 + 左侧约 1/3 曲绘槽(写完整题号 + 该题 CF rating)+ 白色达成率盒(下面两角直角,与底带连成一整块)+ 底带左侧写限时 + 右下角 DX 分数。官方的难度名牌(MASTER)不放。UI_NUM_Score_0001111_*:≥97% 金、80–96.99% 红、<80% 蓝(就这三色;橙色/灰色是 CHUNITHM 的,本作没有)。小数点用本族[13]并压到数字基线上。UI_GAM_Rank_*(不用页签标题那套区间图);合格/不合格用stamp-*印 + 红/绿心 + 「合格 · 4 / 4 道通关」一行。文档与验证
docs/dan.md记录版式换算、评分口径、数字图集与字距、以及踩过的坑。scripts/dan-settlement-e2e.mjs:三场景 E2E(满分 / 分数拉开 / 一道超时取消),除了 DOM 断言还有一层逐像素探针(遮罩染色、白框留白、金色图集等)。scripts/export-original-card.py/scripts/extract-maimai-assets.py:从客户端提取原版素材的开发工具(素材本身不入库以外的用途)。验证:
node --test tests/*.test.ts314/314、E2E「结果:全部通过」、像素探针 0 FAIL。素材版权
public/assets/maimai/*.png是 maimai DX(© SEGA)的游戏素材,只用于还原界面观感,不覆盖仓库原有许可。